package com.dandelion.common.service;

import com.dandelion.common.dao.auto.mapper.AddressTreeMapper;
import com.dandelion.common.dao.auto.mapper.CategoryTreeMapper;
import com.dandelion.common.dao.auto.mapper.CustomServiceMapper;
import com.dandelion.common.dao.auto.pojo.*;
import com.dandelion.common.dao.manual.DictDataDao;
import com.dandelion.common.domain.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DictDataService {
    public static final String PROV_PARENT_CODE = "0";
    public static final int TOP_PARENT_CAT_ID = 0;

    @Autowired
    private DictDataDao dictDataDao;

    @Autowired
    private AddressTreeMapper addressTreeMapper;

    @Autowired
    private CategoryTreeMapper categoryTreeMapper;

    @Autowired
    private CustomServiceMapper customServiceMapper;

    public List<CategoryVO> getAllCategoryTee() {
        return dictDataDao.selectAllCategoryList();
    }

    public List<AddressTreeVO> getAddressList(String provinceCode) {
        return dictDataDao.selectAddressList(provinceCode);
    }

    public List<CustomServiceVO> getCustomServiceByTopCategoryId(int topCatId) {
        return dictDataDao.selectCustomServiceByTopCategoryId(topCatId);
    }

    public String getCustomServiceName(Integer svrId) {
        if (svrId == null || svrId <= 0) {
            return StringUtils.EMPTY;
        }

        return dictDataDao.selectCustomServiceNameById(svrId);
    }

    public Map<String, String> getAddressNameAsMap(Set<String> addrCodeSet) {
        if (CollectionUtils.isEmpty(addrCodeSet)) {
            return Collections.emptyMap();
        }

        return getAddressNameAsMapInternal(Lists.newArrayList(addrCodeSet));
    }

    private Map<String, String> getAddressNameAsMapInternal(List<String> addrCodeList) {
        AddressTreeCriteria criteria = new AddressTreeCriteria();
        criteria.createCriteria().andCodeIn(addrCodeList);
        List<AddressTree> allList = addressTreeMapper.selectByExample(criteria);

        if (CollectionUtils.isEmpty(allList)) {
            return Collections.emptyMap();
        }

        return allList
                .stream()
                .collect(Collectors.toMap(AddressTree::getCode, AddressTree::getName));
    }

    public String getCatNameById(Integer svrCatId) {
        if (svrCatId == null || svrCatId <= 0) {
            return StringUtils.EMPTY;
        }
        return dictDataDao.selectCatNameById(svrCatId);
    }

    public String getExprComNameById(Integer comId) {
        if (comId == null || comId <= 0) {
            return StringUtils.EMPTY;
        }
        return dictDataDao.getExprComNameById(comId);
    }


    public Map<Integer, String> getSvrNameByIdSetAsMap(Set<Integer> svrIdSet) {
        if (CollectionUtils.isEmpty(svrIdSet)) {
            return Collections.emptyMap();
        }

        return getAllSvrNameAsMapInternal(Lists.newArrayList(svrIdSet));
    }

    private Map<Integer, String> getAllSvrNameAsMapInternal(List<Integer> svrIdList) {
        CustomServiceCriteria criteria = new CustomServiceCriteria();
        criteria.createCriteria().andIdIn(svrIdList);

        List<CustomService> serviceList = customServiceMapper.selectByExample(criteria);
        if (CollectionUtils.isEmpty(serviceList)) {
            return Collections.emptyMap();
        }

        return serviceList
                .stream()
                .collect(Collectors.toMap(CustomService::getId, CustomService::getName));
    }

    public Map<Integer, String> getCategoryNameByIdListAsMap(Set<Integer> catIdList) {
        if (CollectionUtils.isEmpty(catIdList)) {
            return Collections.emptyMap();
        }

        return getCategoryNameByIdListAsMapInternal(Lists.newArrayList(catIdList));
    }

    private Map<Integer, String> getCategoryNameByIdListAsMapInternal(List<Integer> catIdList) {
        CategoryTreeCriteria criteria = new CategoryTreeCriteria();
        criteria.createCriteria().andIdIn(catIdList);
        List<CategoryTree> allList = categoryTreeMapper.selectByExample(criteria);
        if (CollectionUtils.isEmpty(allList)) {
            return Collections.emptyMap();
        }

        return allList
                .stream()
                .collect(Collectors.toMap(CategoryTree::getId, CategoryTree::getName));
    }

    public List<CategoryVO> getCategoryList(Integer parentId) {
        if (parentId == null || parentId < 0) {
            parentId = TOP_PARENT_CAT_ID;
        }
        return dictDataDao.selectCategoryList(parentId);
    }

    public List<ExpressComponayVO> getExprCompanyList() {
        return dictDataDao.selectAllExprCompany();
    }

    public Map<Integer, String> getExprCompanyAsMap() {
        List<ExpressComponayVO> values = dictDataDao.selectAllExprCompany();
        if (CollectionUtils.isEmpty(values)) {
            return Collections.emptyMap();
        }

        return values.stream().collect(Collectors.toMap(vo -> NumberUtils.toInt(vo.getId()), ExpressComponayVO::getName, (v1, v2) -> v1));
    }

    public List<CategoryServiceRelationVO> getTopCatAndServices() {
        List<CategoryVO> topCatList = dictDataDao.selectCategoryList(TOP_PARENT_CAT_ID);
        if (CollectionUtils.isEmpty(topCatList)) {
            return Lists.newArrayList();
        }
        List<CategoryServiceRelationVO> relationVOList = new ArrayList<>(topCatList.size());
        for (CategoryVO topCat : topCatList) {
            List<CustomServiceVO> svrList = dictDataDao.selectCustomServiceByTopCategoryId(Integer.parseInt(topCat.getId()));

            CategoryServiceRelationVO relation = new CategoryServiceRelationVO();
            relation.setId(topCat.getId());
            relation.setName(topCat.getName());
            relation.setIsLeaf(topCat.getIsLeaf());
            relation.setSvrList(svrList);

            relationVOList.add(relation);
        }
        return relationVOList;
    }
}
